package org.karelun.ideaboard.edit.ui.cdo.action;

import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.karelun.ideaboard.edit.action.ITransactionActionBarContributor;
import org.karelun.ideaboard.internal.edit.ActionRegistry;

public class TransactionEditingDomainActionBarContributor extends MultiPageEditorActionBarContributor 
			implements ITransactionActionBarContributor, IPropertyListener {

	protected IEditorPart activeEditor;

	protected DeleteAction deleteAction;

	protected CutAction cutAction;

	protected CopyAction copyAction;

	protected PasteAction pasteAction;

	protected UndoAction undoAction;

	protected RedoAction redoAction;

	public static final int ADDITIONS_LAST_STYLE = 0x1;

	protected int style;

	public TransactionEditingDomainActionBarContributor() {
		super();
	}

	public TransactionEditingDomainActionBarContributor(int style) {
		super();
		this.style = style;
	}

	@Override
	public void init(IActionBars actionBars) {
		ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();

		deleteAction = createDeleteAction();
		deleteAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
		actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),deleteAction);

		cutAction = createCutAction();
		cutAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
		actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), cutAction);

		copyAction = createCopyAction();
		copyAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),copyAction);

		pasteAction = createPasteAction();
		pasteAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(),pasteAction);

		undoAction = createUndoAction();
		undoAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
		actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(),undoAction);

		redoAction = createRedoAction();
		redoAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
		actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(),redoAction);

		super.init(actionBars);
	}

	protected CopyAction createCopyAction() {
		return new CopyAction();
	}

	protected CutAction createCutAction() {
		return new CutAction();
	}

	protected PasteAction createPasteAction() {
		return new PasteAction();
	}

	protected DeleteAction createDeleteAction() {
		return new DeleteAction(removeAllReferencesOnDelete());
	}

	protected RedoAction createRedoAction() {
		return new RedoAction();
	}

	protected UndoAction createUndoAction() {
		return new UndoAction();
	}

	protected boolean removeAllReferencesOnDelete() {
		return false;
	}

	public void shareGlobalActions(IPage page, IActionBars actionBars) {
		if (!(page instanceof IPropertySheetPage)) {
			actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),deleteAction);
			actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(),cutAction);
			actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),copyAction);
			actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(),pasteAction);
		}
		actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(),undoAction);
		actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(),redoAction);
	}

	public IEditorPart getActiveEditor() {
		return activeEditor;
	}

	@Override
	public void setActiveEditor(IEditorPart part) {
		super.setActiveEditor(part);
		if (part != activeEditor) {
			if (activeEditor != null) {
				deactivate();
			}

			if (part instanceof IEditingDomainProvider) {
				activeEditor = part;
				activate();
			}
		}
	}

	public void deactivate() {
		activeEditor.removePropertyListener(this);

		deleteAction.setActiveWorkbenchPart(null);
		cutAction.setActiveWorkbenchPart(null);
		copyAction.setActiveWorkbenchPart(null);
		pasteAction.setActiveWorkbenchPart(null);
		undoAction.setActiveWorkbenchPart(null);
		redoAction.setActiveWorkbenchPart(null);

		ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
				: activeEditor.getEditorSite().getSelectionProvider();

		if (selectionProvider != null) {
			selectionProvider.removeSelectionChangedListener(deleteAction);
			selectionProvider.removeSelectionChangedListener(cutAction);
			selectionProvider.removeSelectionChangedListener(copyAction);
			selectionProvider.removeSelectionChangedListener(pasteAction);
		}
	}

	public void activate() {
		activeEditor.addPropertyListener(this);

		deleteAction.setActiveWorkbenchPart(activeEditor);
		cutAction.setActiveWorkbenchPart(activeEditor);
		copyAction.setActiveWorkbenchPart(activeEditor);
		pasteAction.setActiveWorkbenchPart(activeEditor);
		undoAction.setActiveWorkbenchPart(activeEditor);
		redoAction.setActiveWorkbenchPart(activeEditor);

		ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
				: activeEditor.getEditorSite().getSelectionProvider();

		if (selectionProvider != null) {
			selectionProvider.addSelectionChangedListener(deleteAction);
			selectionProvider.addSelectionChangedListener(cutAction);
			selectionProvider.addSelectionChangedListener(copyAction);
			selectionProvider.addSelectionChangedListener(pasteAction);
		}
		update();
	}

	public void update() {
		ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
				: activeEditor.getEditorSite().getSelectionProvider();

		if (selectionProvider != null) {
			ISelection selection = selectionProvider.getSelection();
			IStructuredSelection structuredSelection = selection instanceof IStructuredSelection ? (IStructuredSelection) selection
					: StructuredSelection.EMPTY;

			deleteAction.updateSelection(structuredSelection);
			cutAction.updateSelection(structuredSelection);
			copyAction.updateSelection(structuredSelection);
			pasteAction.updateSelection(structuredSelection);
		}
		undoAction.update();
		redoAction.update();
	}

	@Override
	public void setActivePage(IEditorPart activeEditor) {
		// Do nothing
	}

	@Override
	public void menuAboutToShow(IMenuManager menuManager) {
		// Add our standard marker.
		//
		if ((style & ADDITIONS_LAST_STYLE) == 0) {
			menuManager.add(new Separator("additions"));
		}
		menuManager.add(new Separator("edit"));

		// Add the edit menu actions.
		//
		menuManager.add(new ActionContributionItem(undoAction));
		menuManager.add(new ActionContributionItem(redoAction));
		menuManager.add(new Separator());
		menuManager.add(new ActionContributionItem(cutAction));
		menuManager.add(new ActionContributionItem(copyAction));
		menuManager.add(new ActionContributionItem(pasteAction));
		menuManager.add(new Separator());
		menuManager.add(new ActionContributionItem(deleteAction));
		menuManager.add(new Separator());

		if ((style & ADDITIONS_LAST_STYLE) != 0) {
			menuManager.add(new Separator("additions"));
			menuManager.add(new Separator());
		}
		// Add our other standard marker.
		//
		menuManager.add(new Separator("additions-end"));

		addGlobalActions(menuManager);
	}

	protected void addGlobalActions(IMenuManager menuManager) {
	}

	public void propertyChanged(Object source, int id) {
		update();
	}
	
	private ActionRegistry actionRegistry=new ActionRegistry();
	
	@Override
	public void registerAction(String actionId, IAction action) {
		actionRegistry.registerAction(actionId, action);
		getActionBars().setGlobalActionHandler(actionId, action);
	}
	
	@Override
	public void removeAction(String actionId) {
		actionRegistry.removeAction(actionId);
	}
}
